<?php

namespace control;
/*
*工艺路线类
*/

class routingClass extends adIndexClass
{
    private const page    = 'routing';
    private const table   = 'routing';
    private const tableMx = 'routing_detail';
    private const title   = '工艺路线';
    private array $markOption = ['是', '否'];
    private array $methodOption = ['免检', '巡检', '全检'];
    private array $workType = ['手动' => '手动', '前工序' => '自动-前工序产量', '后工序' => '自动-后工序产量'];
    private array $valuationType = ['班组计件', '个人计件'];

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {
        switch ($fun) {
            default:
                $tr = [
                    'orderNo'          => [
                        'name'  => "工艺路线编码",
                        'width' => 150,
                        'sort' => 1,
                    ],
                    'description'  => [
                        'name'  => '工艺路线描述',
                        'width' => 300,
                    ],
                    'materialTypeId'         => [
                        'name'  => '物料分类',
                        'width' => 200,
                    ],
                    'materialId'          => [
                        'name'  => '物料名称',
                        'width' => 400,
                    ],
                    'isDefault'          => [
                        'name'  => '是否默认',
                        'width' => 70,
                    ],
                    'state'          => [
                        'name'  => '状态',
                        'width' => 150,
                    ],
                    'time'          => [
                        'name'  => '创建日期',
                        'width' => 200,
                        'sort' => 1,
                    ]
                ];
        }
        return $tr;
    }

    /*列表页-查询条件*/
    public function routingListOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "工艺路线编码" => text(array("name" => "orderNo")).
                        hidden(array("name" => "targetId", "value" => $this->get('id'))),
                    "工艺路线描述"   => text(array("name" => "text")),
                    '物料编码' => text(array("name" => "code")),
                ],
                [
                    '物料名称' => text(array("name" => "materialName")),
                    "创建日期" => text(array("name" => "createTime", 'laydate' => ['type' => 'date', 'range' => '~'])),
                    '是否默认' => select(array("name" => "isDefault", "option" => ['是', '否'])),
                ],
                [
                    "状态" => select(["name" => "state", 'option' => ['停用', '启用']]),
                ]
            ]
        ],1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /**
     * 物料-工艺路线
     *
     * @return bool|string
     */
    public function routingList(): bool|string
    {

        $html = $this->routingListOptions(false);
        //控件
        $button = '';
        $json['html'] = $this->search($html, layout: 'pop', toolButton: $button);
        return json_encode($json, 320);
    }

    public function routingListSearch(): bool|string
    {
        $materialId = $this->post('targetId');
        //like查询数组
        $like = array(
            "orderNo"     => $this->post('orderNo'),//入库单号
            "description" => $this->post('text'),//供应商
            "materialId" => $materialId,
        );
        //全等查询数组
        $equal = array(
            "state"      => $this->post('state'),//状态
            "type"       => 1,
            "coid"       => self::$coid
        );
        $and   = "";
        $mAnd  = '';
        if ($this->post('code')) {
            $mAnd .= " and code like '%" . $this->post('code') . "%'";
        }
        if ($this->post('materialName')) {
            $mAnd .= " and name like '%" . $this->post('materialName') . "%'";
        }
        if ($mAnd) {
            $material = query('material',"1=1".$mAnd,'id');
            $material['id'] = $material['id']?:' ';
            $and .= " and materialId like '%{$material['id']}%'";
        }
        if ($this->post('createTime')) {
            $and .= self::timeComparison($this->post('createTime'));
        }
        if ($this->post('isDefault')) {
            $isDefault = $this->post('isDefault') == '是' ? 1 : 0;
            $and       .= " and isDefault = $isDefault";
        }
        //排序
        $orderBy = $this->listSort(array(
            "search"  => $this->post('list_sort_key') ?: 'updateTime',
            "sort" => $this->post('list_sort') ?: "desc",
            "array"   => array(),
        ));
        //获取查询结果
        $where = search(array("like" => $like, "=" => $equal)) . $and;
        $page  = $this->page(array("table" => self::table, "where" => $where, "order" => $orderBy['orderBy']));
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array("");
        //获取记录
        $url = root . "control/adIndex.html?cla=" . self::page;
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate = array(
                "edit"   => array("title" => "编辑", "click" => "newIframe('" . self::title . "详情','" . $url . "&fun=edit&id=" . $array['id'] . "')"),
                "detail" => array("title" => self::title . "详情", "click" => "newIframe('" . self::title . "详情','" . $url . "&fun=detail&id=" . $array['id'] . "')"),
            );
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case 'materialTypeId':
                        $row[] = materialClass::getTypePath($array['materialTypeId']);
                        break;
                    case 'materialId':
                        $row[] = self::getMaterialName(explode(',', $array['materialId']));
                        break;
                    case 'isDefault':
                        $row[] = $array['isDefault'] ? '是' : '否';
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        //生成页面
        $li = $this->li(array(
            "body" => $body,
            "install" => $installSearch,
            "button" => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page" => $page['para'],
        ));
        //返回
        $json['html'] = $page['hint'] . "<form name='routingListForm'>" . $li . "</form>" . $page['button'] . clear;
        return json_encode($json, 320);
    }
    public static function getMaterialName(array|string $materialId): string
    {
        $temp = '';
        if (!is_array($materialId)) {
            if ($materialId) {
                $temp  .= materialClass::getName($materialId);
            }
        } else {
            foreach ($materialId as $id) {
                $temp .= materialClass::getName($id) . ',';
            }
            $temp = rtrim($temp, ',');
        }
        return $temp;
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    "工艺路线编码" => text(array("name" => "orderNo")),
                    "工艺路线描述"   => text(array("name" => "text")),
                    "物料编码"   => text(array("name" => "code")),
                ],
                [
                    "物料名称"   => text(array("name" => "materialName")),
                    "创建日期" => text(array("name" => "createTime", 'laydate' => ['type' => 'date', 'range' => '~'])),
                    "是否默认" => select(array("name" => "isDefault", "option" => ['是', '否'])),
                ],
                [
                    "状态" => select(["name" => "state", 'option' => ['停用', '启用']]),
                ]
            ]
        ]);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /*列表-查询条件*/
    public function home()
    {
        $html = $this->homeOptions(false);
        //控件
        $button = "";
        $url = root . "control/adIndex.html?cla=" . self::page;
        if ($this->power(self::page, "edit")) {
            $button .= "<span onclick=\"newIframe('" . self::title . "详情','" . $url . "&fun=edit')\" class='spanButton'>新增</span>\n";
        }
        if ($this->power(self::page, "del")) {
            $button .= "<span class='spanButton' onclick=\"layer('{$this->get('cla')}', 'operate', {'act': 'del'})\">删除</span>\n";
        }
        if ($this->power(self::page, "edit")) {
            $button .= "<span onclick=\"layer('{$this->get('cla')}','stateSwitch',{type:'启用'})\" class='spanButton'>启用</span>\n";
            $button .= "<span onclick=\"layer('{$this->get('cla')}','stateSwitch',{type:'停用'})\" class='spanButton'>停用</span>\n";
        }
        if ($this->power(self::page, 'import')) {
            $button .="<span class='spanButton' onclick=\"layer('importTemplate','importFrame',{cla:'".self::page."'})\">导入</span>";
        }
        //返回
        return $this->homeFun($this->search($html, layout: 'pop', toolButton: $button));
    }

    /*客户列表-查询结果*/
    public function homeSearch()
    {
        //like查询数组
        $like = array(
            "orderNo"     => $this->post('orderNo'),//入库单号
            "description" => $this->post('text'),//供应商
        );
        //全等查询数组
        $equal = array(
            "state" => $this->post('state'),//状态
            "type"  => 1,
            "coid"  => self::$coid
        );
        $and   = "";
        $mAnd  = '';
        if ($this->post('code')) {
            $mAnd .= " and code like '%" . $this->post('code') . "%'";
        }
        if ($this->post('materialName')) {
            $mAnd .= " and name like '%" . $this->post('materialName') . "%'";
        }
        if ($mAnd) {
            $material = query('material',"1=1".$mAnd,'id');
            $material['id'] = $material['id']?:' ';
            $and .= " and materialId like '%{$material['id']}%'";
        }
        if ($this->post('createTime')) {
            $and .= self::timeComparison($this->post('createTime'));
        }
        if ($this->post('isDefault')) {
            $isDefault = $this->post('isDefault') == '是' ? 1 : 0;
            $and       .= " and isDefault = $isDefault";
        }
        //排序
        $orderBy = $this->listSort(array(
            "search"  => $this->post('list_sort_key') ?: 'updateTime',
            "sort" => $this->post('list_sort') ?: "desc",
            "array"   => array(),
        ));
        //获取查询结果
        $where = search(array("like" => $like, "=" => $equal)) . $and;
        $page  = $this->page(array("table" => self::table,"where" => $where, "order" => $orderBy['orderBy']));

        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("listForm", "listId")
        );
        //获取记录
        $url = root . "control/adIndex.html?cla=" . self::page;
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate = array(
                "box"    => array("name" => "listId", "value" => $array['id']),
                "edit"   => array("title" => "编辑", "click" => "newIframe('" . self::title . "详情','" . $url . "&fun=edit&id=" . $array['id'] . "')"),
                "detail" => array("title" => self::title . "详情", "click" => "newIframe('" . self::title . "详情','" . $url . "&fun=detail&id=" . $array['id'] . "')"),
            );
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case 'materialTypeId':
                        $row[] = materialClass::getTypePath($array['materialTypeId']);
                        break;
                    case 'materialId':
                        $row[] = self::getMaterialName(explode(',', $array['materialId']));
                        break;
                    case 'isDefault':
                        $row[] = $array['isDefault'] ? '是' : '否';
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        //控件
        $button = "";
        //生成页面
        $li = $this->li(array(
            "body" => $body,
            "install" => $installSearch,
            "button" => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page" => $page['para'],
        ));
        //返回
        $json['html'] = $page['hint'] . $button . "<form name='listForm'>" . $li . "</form>" . $page['button'] . clear;
        return json_encode($json, 320);
    }

    /**
     * 下载模板
     */
    public function downloadModel()
    {
        $templateId = $this->get('templateId');
        if (!$this->power(self::page, 'import')) {
            $_SESSION['warn'] = '你还没有导入的权限';
        }else {
            $exampleData[] = [
                '总成工艺路线', '产成品->零部件',  'SF-C10-07风罩模具','SF-C10-07', '否', '测试数据', 'OP01', '冲压', '否', '否', '免检', '班组计件', 2, '手动',
            ];
            $exampleData[] = [
                '总成工艺路线', '产成品->零部件', 'SF-C10-07风罩模具','SF-C10-07', '否', '测试数据', 'OP02', '表面处理', '否', '否', '免检', '班组计件', 2, '手动',
            ];
            $excel    = $this->excelHead();
            $fileName = self::title.'导入模板-'.importTemplateClass::getName($templateId).'.xlsx';
            $filePath = $excel->fileName($fileName, 'sheet1');
            $format = new \Vtiful\Kernel\Format($filePath->getHandle());
            $templateField = importTemplateClass::templateField(self::page, 'importFieldInit', id:$templateId);
            $index         = 0;
            foreach ($templateField as $k => $array) {
                if ($array['display']){
                    $backgroundStyle=null;
                    if (importTemplateClass::getIsMustValue($this->importFieldInit(), $array['columnName'])){
                        //必填项判断
                        $backgroundStyle  = $format->background(
                            0xFFC04B
                        )->toResource();
                    }
                    $filePath->insertText(0, $index, $array['aliasName'],'',$backgroundStyle);
                    foreach ($exampleData as $y=>$example){
                        $exampleVal = match ($array['columnName']){
                            '工艺路线描述'=>$example[0],
                            '物料分类'=>$example[1],
                            '物料名称'=>$example[2],
                            '规格型号'=>$example[3],
                            '尾工序自动入库'=>$example[4],
                            '备注'=>$example[5],
                            '工序编号'=>$example[6],
                            '工序名称'=>$example[7],
                            '工序委外'=>$example[8],
                            '工序节点'=>$example[9],
                            '检验方式'=>$example[10],
                            '计价方式'=>$example[11],
                            '计件单价'=>$example[12],
                            '报工方式'=>$example[13],
                            default=>'',
                        };
                        $filePath->insertText($y+1, $index, $exampleVal);
                    }
                    $index++;
                }
            }
            $text   = $this->control['name'] . "下载了" . self::title . "导入模板";
            $this->logText(["type" => self::page, "text" => $text]);
            $this->excelOutPut($filePath,$fileName);
            exit(0);
        }
        header("Location:" . getenv("HTTP_REFERER"));
    }


    /*数据导入*/
    public function importData()
    {
        $templateId = $this->post('templateId');
        if (!$this->power(self::page, 'import')) {
            $json['warn'] = '你还没有导入的权限';
        } else {
             $fomatArray = [];//导入数据格式同一为TYPE_STRING
            foreach ($this->importFieldInit() as $value){
                $fomatArray[] = \Vtiful\Kernel\Excel::TYPE_STRING;
            }
            $data = $this->importHead(format: $fomatArray);
            $x    = 0;
            $text = '';
            $headArray = [];
            $row_list=0;
            foreach ($data as $i => $row) {
                $row_list++;
                if ($i==0){
                    $templateField = importTemplateClass::templateField(self::page, 'importFieldInit', id:$templateId);
                    $headArray = importTemplateClass::combinHead($templateField,$row);
                }
                if ($i > 0) {

                    $rowData = formSubArray($row);
                    //只接收模板中选中的字段的值
                    $item = [];
                    foreach ($headArray as $index=>$headName){
                        $item[$headName] = $rowData[$index]??'';
                    }
                    //初始化未被模板需要的字段的值
                    foreach ($this->importFieldInit() as $value){
                        $item[$value['columnName']] = $item[$value['columnName']]??'';
                    }

                    $routing = query(self::table, "coid = '" . self::$coid . "' and description = '$item[工艺路线描述]'");
                    //工序
                    $process = query('process', "coid = '" . self::$coid . "' and orderNo = '$item[工序编号]'");
                    //多级分类分割
                    $typeArr = explode("&gt;", $item['物料分类']);
                    if (is_array($typeArr)) {
                        $pid = '0';
                        foreach ($typeArr as $name) {
                            $type = query('material_type', "name = '$name' and pid = '$pid' and coid = '" . self::$coid . "'");
                            if (empty($type['id'])) {
                                break;
                            } else {
                                $pid = $type['id'];
                            }
                        }
                    }
                    $materialIdArr = [];
                    if (!empty($item[2])) {
                        $materialNameArr = explode('，', $item['物料名称']);
                        $materialModelArr = explode('，', $item['规格型号']);
                        foreach ($materialNameArr as $k=>$name) {
                            $material = query('material', "coid = '" . self::$coid . "' and name = '$name' and model = '$materialModelArr[$k]'");
                            if (!empty($material['id'])) {
                                $materialIdArr[] = $material['id'];
                            }
                        }
                    }
                    $field      = [
                        'isDefault'      => 0,
                        'text'           => $item['备注'],
                        'description'    => $item['工艺路线描述'],
                        'materialTypeId' => $type['id'] ?? '',
                        'materialId'     => $materialIdArr ? implode(',', $materialIdArr) : '',
                        'endProcessIn'   => $item['尾工序自动入库'],
                    ];
                    if ($field['materialId']){
                        $field['materialTypeId'] = '';
                    }
                    $annotation = [
                        'description'  => '描述',
                        'endProcessIn' => '尾工序自动入库'
                    ];
                    $rules      = [
                        'description'  => 'required',
                        'endProcessIn' => 'required'
                    ];
                    // 校验是否符合规则
                    $vt     = new \verify();
                    $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
                    if ($result === false) {
                        $text .= "\n第【{$row_list}】行，" . $vt->getErrs()[0];
                    } elseif (empty($process['id'])) {
                        $text .= "\n第【{$row_list}】行，未通过工序编号找到工序";
                    } elseif (!empty($item['检验方式']) && !in_array($item['检验方式'], $this->methodOption)) {
                        $text .= "\n第【{$row_list}】行，所填检验方式不在可选范围内";
                    } elseif (empty($field['materialId']) && empty($field['materialTypeId'])) {
                        $text .= "\n第【{$row_list}】行，请选择至少选择物料或物料分类其中一种";
                    } else {
                        // 新增
//                        if (!empty($field['materialId']) && static::total(array('table' => self::table, "where" => "materialId = '$field[materialId]' and isDefault = 1 and type = 1")) == 0) {
//                            $field['isDefault'] = 1;
//                        }
//                        if (empty($field['materialId']) && static::total(array('table' => self::table, "where" => "materialTypeId = '$field[materialTypeId]' and isDefault = 1 and type = 1")) == 0) {
//                            $field['isDefault'] = 1;
//                        }
                        if (empty($routing['id'])) {
                            $userNo = codeTemplateClass::generateCode(self::page, [
                                'prefix' => 'POP',
                                'table'  => self::table,
                                'field'  => 'orderNo',
                                'where'  => " and coid = '" . self::$coid . "'",
                            ], $field);
                            $field  = array_merge($field, [
                                'id'      => suiji(),
                                'coid'    => self::$coid,
                                'orderNo' => $userNo,
                                'state'   => '启用',
                                'type'    => 1,
                                'stid'    => self::$stid,
                                'source'  => '新建'
                            ]);
                            $warn   = static::insert([
                                "table" => self::table,
                                "field" => $field,
                            ]);
                        } else {
                            $warn        = static::update([
                                "table" => self::table,
                                "field" => $field,
                                'where' => "id = '$routing[id]'",
                            ]);
                            $field['id'] = $routing['id'];
                        }
                        if (in_array($warn, ["新增成功", "更新成功"])) {
                            //导入明细
                            $mxField = [
                                'id'            => suiji(),
                                'coid'          => self::$coid,
                                'orderId'       => $field['id'],
                                'processId'     => $process['id'],
                                'mark'          => $item['工序节点'] ?: '否',
                                'price'         => $item['计件单价'] ?: 0,
                                'method'        => $item['检验方式'] ?: '免检',
                                'workType'      => $item['报工方式'] ?: '手动',
                                'isOut'         => $item['工序委外'] ?: '否',
                                'valuationType' => $item['计价方式'] ?: '班组计件',
                            ];
                            if ($mxField['isOut'] == '是') {
                                $mxField['mark']   = '否';
                                $mxField['method'] = '免检';
                            }
                            $warn = static::insert([
                                "table" => self::tableMx,
                                "field" => $mxField,
                            ]);
                            if ($warn == '新增成功') {
                                $x++;
                                if (static::total(array('table' => self::table, "where" => "materialId like '%$field[materialId]%' and  materialTypeId = '$field[materialTypeId]' and isDefault = 1 and type = 1")) > 2) {
                                    update(array('table' => self::table, 'field' => array('isDefault' => 0), 'where' => "materialId = '$field[materialId]' and type = 1  and id !='$field[id]'"));
                                }
                                $text .= "第【{$row_list}】行:导入成功<br>";
                            } else {
                                $text .= "第【{$row_list}】行:导入失败<br>";
                            }
                        } else {
                            $text .= "第【{$row_list}】行导入失败：$warn<br>";
                        }
                    }
                }
            }
            $total = count($data)-1;
            $json['data'] = [
                'text'=>$text,
                'title'=>"您导入了{$total}条数据，成功{$x}条，失败".($total-$x)."条",
            ];
            $text = $this->control['name'] . '导入了文件：' . $_FILES['file']['name'] . '：' . $text;
            $this->logText(["type" => self::page, "text" => $text]);
            $json['warn'] = 2;
        }
        return json_encode($json,320);
    }

    /**
     * 编辑页
     * @return string
     */
    public function edit(): string
    {
        $id         = $this->get('id') ?: suiji();
        $info       = query(self::table, " id = '" . $id . "' ");
        $sourceType = $this->get('sourceType');
        $button[]   = [
            'style' => 'li-btn-blue-bg',
            "name"  => "保存",
            "type"  => "点击事件",
            "title" => "保存",
            'fun'   => "subForm('" . self::page . "EditForm','" . root . "control/adIndex.html?cla=" . self::page . "&fun=editEdit&from=" . $sourceType . "')",
        ];

        $button[] = [
            "name"  => "保存为模板",
            "type"  => "点击事件",
            "title" => "保存为模板",
            'fun'   => "subForm('" . self::page . "EditForm','" . root . "control/adIndex.html?cla=" . self::page . "&fun=editEdit&type=template')"
        ];
        if (empty($info['id'])) {
            $button[] = [
                "name"  => "从模板新建",
                "type"  => "点击事件",
                "title" => "从模板新建",
                'fun'   => "layer('" . self::page . "','addTemplate',{id:'" . $info['id'] . "'})"
            ];
        }

        $tr[]   = ['', '工序名称', '工序委外', '工序节点', '检验方式', '计价方式', '计件单价(' . static::$unit . '）', '报工方式'];//'计件单位',
        $result = find(array(
            'field' => "id as mxId,processId,isOut,mark,method,valuationType,price,workType",
            'table' => self::tableMx." where orderId = '$info[id]' order by list"
        ));
        if(count($result['array']) > 0) {
            foreach ($result['array'] as $k=>$array) {
                $array['list'] = $k+1;
                $array['mxId'] = $sourceType === 'template' ? self::getId() : $array['mxId'];
                $tr[] = $this->listRow($array);
            }
        }else{
            $tr[] = $this->listRow(['mxId'=>self::getId(), 'list'=>1]);
        }
        $table         = $this->listTable(array('tr' => $tr, 'end' => true));
        $materialArr  = array_filter((array)explode(',', $info['materialId']));
        $materialTr[] = ['', '物料编码', '物料名称', '规格型号'];
        foreach ($materialArr as $k=>$materialId) {
            $material     = query('material', " id = '$materialId'");
            $materialTr[] = [
                componentClass::tablePperation($k+1,"delTableRow(this)").
                hidden(array('name' => 'pMaterialId[]', 'value' => $materialId)),
                $material['code'],
                $material['name'],
                $material['model'],
            ];
        }
        $list = $this->listTable(array('tr' => $materialTr, 'end' => true));

//        $materialName =materialClass::getName($info['materialId']);
        $id               = $sourceType === 'template' ? self::getId() : $info['id'];
        $materialTypeName = materialClass::getTypePath($info['materialTypeId']);
        //表单
        $data['button'] = $this->tableShowButton($button);
        $body = $this->edit4([
            '基本信息' => [
                [
                    must . "工艺路线描述：" => text(["name" => "description", 'class' => 'text', "value" => $info['description']]),
                    must . "默认工艺"    => radio(array('name' => 'isDefault', 'value' => ['1' => '是', '0' => '否'], 'checked' => $info['isDefault'] ?: 0)),
                    must . "尾工序自动入库：" => radio(array('name' => 'endProcessIn', 'value' => ['是', '否'], 'checked' => $info['endProcessIn'] ?: '否')),
                    "物料分类：" => "<input type='hidden' value='{$info['materialTypeId']}' name='materialTypeId'><span id='materialType'>{$materialTypeName}</span><span class='del-row-button' onclick=\"layer('" . self::page . "','materialType',{id:'" . $info['materialTypeId'] . "'})\" style='margin-left: 10px'>选择</span>",
                    //                    "物料：" => hidden(array('name' => 'materialId', 'value' => $info['materialId'])) . "<span id='materialName'>{$materialName}</span><span class='del-row-button' style='margin-left: 5px' onclick=\"layer('{$this->get('cla')}','addMaterial',$('[name=routingEditForm]').serialize())\">选择</span>",
                ],
                [
                    "作业指导书：" => fileUploadClass::singleUpload(self::page . 'EditForm', self::page, $id, '工艺路线指导书'),
                ],
                [
                    "备注："    => textarea(["name" => "text", "value" => $info['text']]),
                ],
            ]
        ]);
        $body .= $this->editList([
            'id' => 'materialMx',
            'title' => '物料',
            'button' => "<span class='smallButton' onclick=\"layer('{$this->get('cla')}','addMaterial',$('[name=routingEditForm]').serialize())\">选择物料</span>",
            'html' => $list,
        ]);
        $body .= $this->editList([
            'id' => 'materialTable',
            'title' => '明细',
            'html' => $table,
        ]);
        $data['html'] = $this->pageEdit([
            "html"  => $body,
            'hidden' => hidden(['name' => 'id', 'value' => $id]),
        ]);
        //返回
        return $this->tab($data) . $this->js();
    }

    /**
     * Desc : 工序明细
     * User : you name
     * Date : 2024-02-20 14:51
     * @param array $data
     * @return array|false|string
     */
    public function listRow($data=[])
    {
        $list = isset($data['list'])?$data['list']:'';
        $mxId = isset($data['mxId'])&&$data['mxId']?$data['mxId']:self::getId();
        $field = ['processId', 'isOut', 'mark', 'method', 'valuationType', 'price', 'workType'];
        foreach ($field as $item){
            $array[$item] = isset($data[$item])?$data[$item]:$this->post($item);
        }
        $array['isOut'] = $array['isOut'] ? : '否';
        $array['mark'] = $array['mark'] ? : '否';
        $array['workType'] = $array['workType'] ? : '手动';
        if ($array['isOut'] == '是') {
            $method        = '-' . hidden(array('name' => 'method[]'));
            $valuationType = '委外加工费' . hidden(array('name' => 'valuationType[]', 'value' => '委外加工费'));
        } else {
            $method        = select(array('name' => "method[]", 'option' => $this->methodOption, 'value' => $array['method'] ?: '免检'));
            $valuationType = select(array('name' => 'valuationType[]', 'title' => '计价方式', 'option' => $this->valuationType, 'value' => $array['valuationType']));
        }
        $cloneArg = json_encode([
            'cla' => self::page,
            'fun' => 'listRow',
            'copy' => ['processId', 'method', 'valuationType', 'price'],
        ],320);
        $delArg = json_encode([
            'empty' => ['processId', 'method', 'valuationType', 'price'],
        ],320);
        $tr = [
            componentClass::tablePperation($list, "delRows(this,$delArg)","cloneRows(this,$cloneArg)", "addRow(this)"),
            hidden(array('name' => 'mxId[]', 'value' => $mxId)) .
            selectMultiple(array('name' => 'processId[]', 'change' => 'processNo', 'table' => "process", 'where' => "state = '启用' and coid = '" . self::$coid . "' order by orderNo", 'sqlId' => 'id', 'field' => "id,concat(orderNo,'-',name) as name", 'sqlField' => "name", 'title' => '工序名称', 'value' => $array['processId'])),
            radio(array('name' => "isOut[{$mxId}]", 'change' => 'changeType', 'value' => ['是', '否'], 'checked' => $array['isOut'])),
            radio(array('name' => "mark[{$mxId}]", 'value' => $this->markOption, 'checked' => $array['mark'])),
            "<span class='method'>" . $method . "</span>",
            "<span class='valuationType'>" . $valuationType . "</span>",
            text(array('name' => 'price[]', 'class' => 'text', 'other' => self::digitalFiltering('pricePrecision'), 'value' => $array['price']?self::lostZero($array['price'], 'pricePrecision'):'')),
            radio(array('name' => "workType[{$mxId}]", 'value' => $this->workType, 'checked' => $array['workType'])),
        ];
        if($data){
            return $tr;
        }
        $json['html'] = $this->tableMany(['tr' => [$tr], 'thead' => false]);
        return json_encode($json, 320);
    }


    /**
     *添加一行
     */
    public function addRow()
    {
        $res = json_decode($this->listRow(),true);
        $json['data'] = $res['html'];
        return json_encode($json, 320);
    }

    /**
     * 选择分类
     */
    public function materialType(): bool|string
    {
        $all    = self::getDepartmentAll();
        $search          = "<div class='container-left-search-parent flex-box'>
                                ".text(["name" => 'name', 'title' => "搜索分类", 'class' => 'container-left-search', 'other' => " onkeyup='search_left(this,event)' "])."
                                <i class='container-left-search-ico' onclick=\"search_left(document.getElementsByClassName('container-left-search')[0])\"></i>
                                <span class='search-count'></span>
                            </div>";
        $html   = <<<efo
                    <div class="layer-container-main">
                        <div class="container-left" id="container-left" style="position: relative">
                          {$search}
                           <div class="classify-area">
                                $all
                            </div>
                        </div>
                    </div>
<script>
$(document).ready(function(){
    //初始化左侧分类标记和定位
    search_left(document.getElementsByClassName('container-left-search')[0])
});
</script>
<style>
.layer-container-main .container-left{height: 430px;flex: 1;}
.layer-container-main .container-left .classify-area {height: 395px;overflow: auto;}
</style>
efo;

        return $this->layer(array("title" => "选择分类", "height" => 500, "width" => 650, "html" => $html, "button" => false));
    }

    /**
     * 左侧搜索框
     *
     * @return string
     */
    public function getContainerLeftJson(): string
    {
        $option['click'] = "replaceDetail($(this).parent(),'" . self::page . "')";
        $json['html']    = self::getDepartmentAll($option);
        return json_encode($json, 320);
    }

    public static function getDepartmentAll($data = []): string
    {
        // 条件
        $data['where'] = $data['where'] ?? "pid='0'";
        // 点击事件
        $data['click'] = $data['click'] ?? "replaceDetail($(this).parent(),'" . self::page . "')";
        // 结果
        $result = find(['table' => 'material_type', 'where' => $data['where'] . " and coid = '" . self::$coid . "' order by list asc,time asc"]);
        $style  = ($data['where'] == "pid='0'") ? '' : ' class="child-node"';
        $temp   = "<ul {$style} {$data['where']}>";
        $textcontent_ico = "<span class='textcontent_ico'></span>";

        if ($result['array']) {
            foreach ($result['array'] as $value) {
                // 角标
                $arrow = "<span class='arrow'  onclick=\"{$data['click']}\"></span>";
                // 判断下级是否存在
                $data['where'] = " pid='{$value['id']}' ";
                $has           = query('material_type', $data['where']);
                $name          = materialClass::getTypePath($value['id']);
                if ($has['id']) {

                    $temp .= "<li class='arrow-li' data-id='{$value['id']}' title='双击选择此分类' data-name='{$name}'  ondblclick='chooseMaterialType(this)' >{$arrow}<span class='textcontent'>{$textcontent_ico}{$value['name']}</span></li>";
                    $temp .= self::getDepartmentAll($data);
                } else {
                    $temp .= "<li class='arrow-no-li'  data-id='{$value['id']}' title='双击选择此分类' data-name='{$name}' ondblclick='chooseMaterialType(this)' onclick=\"{$data['click']}\"><span class='textcontent'>{$textcontent_ico}{$value['name']}</span></li>";
                }
            }
        }
        $temp .= '</ul>';
        return $temp;
    }

    public function changeType()
    {
        $isOut = $this->post('isOut');
        if (empty($isOut)) {
            $json['warn'] = '不能判断工序是否委外';
        } else {
            if ($isOut == '是') {
                $json['method']        = '-' . hidden(array('name' => 'method[]'));
                $json['valuationType'] = '委外加工费' . hidden(array('name' => 'valuationType[]', 'value' => '委外加工费'));
            } else {
                $json['method']        = select(array('name' => "method[]", 'value' => '免检', 'option' => $this->methodOption));
                $json['valuationType'] = select(array('name' => 'valuationType[]', 'title' => '计价方式', 'option' => $this->valuationType));
            }
            $json['warn'] = 2;
        }
        return json_encode($json, 320);
    }

    public function js(): string
    {
        return <<<eof
<script>

function changeType(e){
    let isOut = e.value;
    $.post(root+'control/adIndex.html?cla=routing&fun=changeType',{isOut:isOut},function(res) {
        if (res.warn ===2){
            $(e).parent().parent().parent().find(".method").empty().append(res.method);
            $(e).parent().parent().parent().find(".valuationType").empty().append(res.valuationType);
        }else{
            msg(res.warn,'error');
        }
    },'json')
}
  //选择分类
         function chooseMaterialType(e){
             let id = $(e).data('id');
             let val = $(e).data('name');
             $("#materialType").html(val);
             $("[name='materialTypeId']").val(id);
             $('#routingMaterialType').hide()
             // $("[name='materialId']").val('');
             // $("#materialName").html('');
               $("#materialMx tbody").empty();
         }
       
    /**排序**/
    function re_list(){
        $("#materialTable tr").each(function(index) {
           $(this).find(".mx_list").html(index);
           // if (index ===1){
           //     $(this).children("td").eq(3).html('-')
           // }
        })
    }
     //添加一行
     function addRow(e){
        // let materialId = $("[name='materialId']").val();
        // if (!materialId){
        //     msg('请先选择物料','error');
        //     return false;
        // }
         $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addRow',{},function (res){
            $(e).closest('tr').after(res.data);
            resetNumber($(e).closest('tbody'))
         },'json');
     }
     //选择生产产品
    function addMaterial(){
             $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=addMaterialEdit',$("form[name='mxForm']").serialize(),function(res) {
                 if (res.warn ==2){
                    $('#routingAddMaterial').hide();
                    // $("[name='materialId']").val(res.id);
                    // $("#materialName").html(res.name);
                    $("[name='materialTypeId']").val('');
                    $("#materialType").html('');
                    $("#materialMx tbody").append(res.html);
                    resetNumber($("#materialMx"))
                 }else{
                     msg(res.warn);
                 }
            },'json');
    }
    //获取工序编号
    function processNo(e){
        let id = e.value;
        $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=processNo',{id:id},function(res) {
                 if (res.warn ==2){
                    $(e).parent().parent().parent().find(".processNo").html(res.data);
                 }
            },'json');
        
    }
    //从模板新建
    function addTemplate(){
        let id = $("form[name='templateForm'] [type='radio']:checked").val();
        if (id){
            $('#routingAddTemplate').hide()
            newIframe('工艺路线详情',root+'control/adIndex.html?cla=routing&fun=edit&sourceType=template&id='+id)
        }else{
            msg('未获取到模板','error')
        }
    }
    //删除模板
    function del_template(id){
        if (id){
            $.post(root+'control/adIndex.html?cla={$this->get('cla')}&fun=delTemplate',{id:id},function(res) {
                 if (res.warn ==2){
                    location.reload();
                 }else{
                      msg(res.warn,'error')
                 }
            },'json');
        }else{
            msg('未找到模板','error')
        }
    }
</script>
eof;

    }

    /**
     * 删除模板
     */
    public function delTemplate(): bool|string
    {
        $id      = $this->post('id');
        $routing = query('routing', "id = '$id' and type = 0");
        if (empty($routing['id'])) {
            $json['warn'] = '未找到此模板';
        } else {
            $warn = delete(array('table' => self::table, 'where' => "id = '$id'"));
            if ($warn == '删除成功') {
                delete(array('table' => self::tableMx, 'where' => "orderId = '$id'"));
                $json['warn'] = 2;
                $text         = $this->control['name'] . "删除了工艺路线模板【{$routing['description']}】, id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
            } else {
                $json['warn'] = $warn;
            }
        }
        return json_encode($json, 320);
    }

    /**
     *选择模板
     * @return bool|string
     */
    public function addTemplate(): bool|string
    {
        $html   =
            text(array("name" => "description", "title" => "工艺路线描述")) .
            text(array("name" => "code", "title" => "物料编码")) .
            text(array("name" => "materialName", "title" => "物料名称")) .
            text(array("name" => "model", "title" => "规格型号"));
        $button = "<input style='margin-left: 5px' onclick=\"addTemplate()\" type='button' class='searchSub' value='确定'>";
        $html   = $this->search($html);
        return $this->layer(array("title" => "选择模板", "height" => 600, "width" => 1000, "html" => $html, "button" => $button));
    }

    /**
     *选择模板
     */
    public function addTemplateSearch(): bool|string
    {
        $and  = " and type = 0";
        $mAnd = "";
        if ($this->post('materialName')) {
            $mAnd .= " and name like '%" . $this->post('materialName') . "%'";
        }
        if ($this->post('code')) {
            $mAnd .= " and code like '%" . $this->post('code') . "%'";
        }
        if ($this->post('model')) {
            $mAnd .= " and model like '%" . $this->post('model') . "%'";
        }
        if ($mAnd) {
            $and .= " and materialId in (select id from material where (source like '%自制%' or source like '%委外%') {$mAnd})";
        }
        $like  = [
            'description' => $this->post('description'),
        ];
        $equal = [
            'coid' => self::$coid,
        ];
        $where = search(["like" => $like, "=" => $equal]) . $and;
        $page  = $this->page([
            "table"   => "routing",
            "where"   => $where,
            'pageNum' => 50,
            "order"   => "`time` ASC",
        ]);
        //获取表头
        $tr[] = ['', '工艺描述', '物料编码', '物料名称', '规格型号', '操作'];
        //获取记录
        foreach ($page['array'] as $array) {
            $material = query('material', "id = '$array[materialId]'");
            $tr[]     = array(
                "<input name='mxId' value='$array[id]' type='radio'>",
                $array['description'],
                $material['code'],
                $material['name'],
                $material['model'],
                "<span class='del-row-button' onclick=\"del_template('{$array['id']}')\">删除</span>"
            );
        }
        $json['html'] = $page['hint'] . "<form name='templateForm'>" . space . $this->tableMany(array("tr" => $tr, "showSort" => true, "page" => $page['para'])) . "</form>" . $page['button'];
        return json_encode($json, 320);
    }


    /**
     * 获取工序号
     * @return bool|string
     */
    public function processNo(): bool|string
    {
        $process = query('process', "id = '" . $this->post('id') . "'");
        if (empty($process['id'])) {
            $json['warn'] = '未找到此工序';
        } elseif ($process['state'] != '启用') {
            $json['warn'] = '此工序未启用';
        } else {
            $json['warn'] = 2;
            $json['data'] = $process['orderNo'];
        }
        return json_encode($json, 320);
    }

    /**
     *选择生产产品
     * @return bool|string
     */
    public function addMaterial(): bool|string
    {
//        $materialTypeId = $this->post('materialTypeId');
//        if ($materialTypeId){
//            $materialType = query('material_type',"id = '$materialTypeId'");
//            $typeHtml = text(array('name'=>'typeName','value'=>$materialType['name'],'other'=>"disabled")).hidden(array('name'=>'type','value'=>$materialTypeId));
//        }else{
        $typeHtml = materialClass::typeSelect(name: 'type');
//        }
        $html   =
            $typeHtml .
            text(array("name" => "code", "title" => "物料编码")) .
            text(array("name" => "materialName", "title" => "物料名称")) .
            text(array("name" => "model", "title" => "规格型号")) .
            hidden(array('name' => 'pMaterialId', 'value' => $this->post('pMaterialId') ? implode(',', $this->post('pMaterialId')) : ''));
        $button = "<input style='margin-left: 5px' onclick=\"addMaterial()\" type='button' class='searchSub' value='提交'>";
        $html   = $this->search($html);
        return $this->layer(array("title" => "添加", "height" => 600, "width" => 1000, "html" => $html, "button" => $button));
    }

    /**
     *添加物料
     */
    public function addMaterialSearch(): bool|string
    {
        $materialId = $this->post('pMaterialId') ? explode(',', $this->post('pMaterialId')) : [];
        $and        = " and (source like '%自制%' or source like '%委外%') and id not in ('" . implode("','", $materialId) . "')";
        $like       = [
            'name'  => $this->post('materialName'),
            'code'  => $this->post('code'),
            'model' => $this->post('model'),
        ];
        $equal      = [
            'state' => '启用',
            'coid'  => self::$coid,
        ];
        if ($this->post('type')) {
            $allTypeId = materialClass::getAllChildTypeId($this->post('type'));
            $and       .= " and typeId in ('" . implode("','", $allTypeId) . "')";
        }
        $where = search(["like" => $like, "=" => $equal]) . $and;
        $page  = $this->page([
            "table"   => "material",
            "where"   => $where,
            'pageNum' => 50,
            "order"   => "`code` ASC,time",
        ]);
        //获取表头
        $checkAll = $this->checkAll("mxForm", "mxId");
        $tr[]     = [$checkAll, '分类', '物料编码', '物料名称', '规格型号'];
        //获取记录
        foreach ($page['array'] as $array) {
            $dominate = array(
                "box" => array("name" => "mxId", "value" => $array['id']),
            );
            $tr[]     = array(
                $this->dominate($dominate),
                materialClass::getTypePath($array['typeId']),
                $array['code'],
                $array['name'],
                $array['model'],
            );
        }
        $json['html'] = $page['hint'] . "<form name='mxForm'>" . space . $this->tableMany(array("tr" => $tr, "showSort" => true, "page" => $page['para'])) . "</form>" . $page['button'];
        return json_encode($json, 320);
    }

    /**
     * 编辑
     *
     * @return bool|string
     */
    public function addMaterialEdit(): bool|string
    {
        $mxIdArr = $this->post('mxId');
        if (!$this->power(self::page, 'edit')) {
            $json['warn'] = '你还没有编辑权限';
        } elseif (self::is_null_array($mxIdArr)) {
            $json['warn'] = '请选择物料';
        } else {
            $materialTr = [];
            foreach ($mxIdArr as $materialId) {
                $material     = query('material', "id = '$materialId'");
                $materialTr[] = [
                    componentClass::tablePperation('',"delTableRow(this)").
                    hidden(array('name' => 'pMaterialId[]', 'value' => $materialId)),
                    $material['code'],
                    $material['name'],
                    $material['model'] ?: ' ',
                ];
            }
            $json['html'] = $this->tableMany(array('tr' => $materialTr, 'thead' => false));
            $json['warn'] = 2;
        }
        return json_encode($json, 320);
    }

    public function editEdit()
    {
        $sourceType       = $this->get('type');
        $fileId           = $this->post('fileId');
        $id               = $this->post('id') ?: self::getId();
        $mxIdArr          = $this->post('mxId') ?: [];
        $processIdArr     = $this->post('processId');
        $markArr          = $this->post('mark');
        $priceArr         = $this->post('price');
        $methodArr        = $this->post('method');
        $valuationTypeArr = $this->post('valuationType');
        $isOutArr         = $this->post('isOut');
        $workTypeArr      = $this->post('workType');

        $field = [
            'isDefault'      => $this->post('isDefault'),
            'text'           => $this->post('text'),
            'description'    => $this->post('description'),
            'materialTypeId' => $this->post('materialTypeId'),
            'materialId'     => $this->post('pMaterialId') ? implode(',', $this->post('pMaterialId')) : '',
            'endProcessIn'   => $this->post('endProcessIn')
        ];
        if ($field['materialId']){
            $field['materialTypeId'] = '';
        }
        $annotation = [
            'description'  => '描述',
            'endProcessIn' => '尾工序自动入库'
        ];
        $rules      = [
            'description'  => 'required',
            'endProcessIn' => 'required'
        ];
        // 校验是否符合规则
        $vt     = new \verify();
        $result = $vt->setAliases($annotation)->validate($field, $rules)->isOk();
        if ($result === false) {
            $json['warn'] = $vt->getErrs()[0];  // 多个规则提示最前面一条
            goto resp;
        }
        $where = " id = '$id' ";
        $info  = query(self::table, $where);
        //判断
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有编辑" . self::title . "的权限";
        } elseif (static::is_null_array($mxIdArr)) {
            $json['warn'] = '请选择工序';
        } elseif (static::is_null_array($processIdArr)) {
            $json['warn'] = '请选择工序';
        } elseif (empty($field['materialId']) && empty($field['materialTypeId'])) {
            $json['warn'] = '请选择至少选择物料或物料分类其中一种';
        } elseif (!empty($field['materialId']) && !empty($field['materialTypeId'])) {
            $json['warn'] = '只能选择物料或物料分类其中一种';
        } elseif ($sourceType !== 'template' && static::total(array('table' => self::table, 'where' => "coid = '" . self::$coid . "' and type = 1 and description = '$field[description]' and id !='$id'")) > 0) {
            $json['warn'] = '已存在此描述';
        } elseif ($sourceType == 'template' && !empty($field['materialId']) && static::total(array('table' => self::table, 'where' => "coid = '" . self::$coid . "' and type = 0 and description = '$field[description]'")) > 0) {
            $json['warn'] = '已存在此模板名称';
        } else {
            $this->startTrans();
//            if (!empty($field['materialId']) && $sourceType !== 'template' && static::total(array('table' => self::table, "where" => "materialId = '$field[materialId]' and isDefault = 1 and type = 1")) == 0) {
//                $field['isDefault'] = 1;
//            }
//            if (empty($field['materialId']) && $sourceType !== 'template' && static::total(array('table' => self::table, "where" => "materialTypeId = '$field[materialTypeId]' and isDefault = 1 and type = 1")) == 0) {
//                $field['isDefault'] = 1;
//            }
            if (!$info['id']) {
                $userNo       = codeTemplateClass::generateCode(self::page, [
                    'prefix' => 'POP',
                    'table'  => self::table,
                    'field'  => 'orderNo',
                    'where'  => " and coid = '" . self::$coid . "'",
                ], $field);
                $field        = array_merge($field, [
                    'id'      => $id,
                    'coid'    => self::$coid,
                    'orderNo' => $userNo,
                    'state'   => '启用',
                    'type'    => 1,
                    'stid'    => self::$stid,
                    'source'  => '新建'
                ]);
                $json['warn'] = static::insert(["table" => self::table, "field" => $field]);
            } else {
                $json['warn'] = static::update([
                    "table" => self::table,
                    "field" => $field,
                    "where" => $where
                ]);
            }
            if ($sourceType === 'template') {
                $userNo     = codeTemplateClass::generateCode(self::page, [
                    'prefix' => 'TEP',
                    'table'  => self::table,
                    'field'  => 'orderNo',
                    'where'  => " and coid = '" . self::$coid . "'",
                ], []);
                $templateId = suiji();
                $warn       = static::insert(["table" => self::table,
                                              "field" => [
                                                  'id'             => $templateId,
                                                  'coid'           => self::$coid,
                                                  'orderNo'        => $userNo,
                                                  'state'          => '启用',
                                                  'type'           => 0,
                                                  'stid'           => self::$stid,
                                                  'source'         => '模板',
                                                  'text'           => $this->post('text'),
                                                  'description'    => $this->post('description'),
                                                  'materialId'     => $this->post('materialId'),
                                                  'materialTypeId' => $this->post('materialTypeId'),
                                              ]]);
                if ($warn != '新增成功') {
                    $json['warn'] = '保存模板失败';
                }
                foreach ($mxIdArr as $k => $nid) {
                    $priceArr[$k] = $priceArr[$k] ?: 0;
                    //新增
                    $warn = static::insert([
                        "table" => self::tableMx,
                        "field" => [
                            'id'            => suiji(),
                            'coid'          => self::$coid,
                            'orderId'       => $templateId,
                            'processId'     => $processIdArr[$k],
                            'mark'          => $markArr[$nid] ?? '否',
                            'price'         => $priceArr[$k],
                            'method'        => $methodArr[$k],
                            'isOut'         => $isOutArr[$nid],
                            'valuationType' => $valuationTypeArr[$k] ?? '班组计件',
                            'workType'      => $workTypeArr[$nid] ?? '手动',
                        ],
                    ]);
                    if (!in_array($warn, ['新增成功', '更新成功'])) {
                        $json['warn'] = '保存模板明细失败';
                        break;
                    }
                }
            }


            foreach ($mxIdArr as $k => $nid) {
                $mx           = query(self::tableMx, "id = '$nid'");
                $priceArr[$k] = $priceArr[$k] ?: 0;
                if ($isOutArr[$nid] == '是') {
                    $markArr[$nid] = '否';
                    $methodArr[$k] = '免检';
                }
                if (!empty($mx['id'])) {
                    //更新
                    $warn = static::update([
                        "table" => self::tableMx,
                        "field" => [
                            'processId'     => $processIdArr[$k],
                            'mark'          => $markArr[$nid] ?? '否',
                            'price'         => $priceArr[$k],
                            'method'        => $methodArr[$k],
                            'isOut'         => $isOutArr[$nid],
                            'valuationType' => $valuationTypeArr[$k] ?? '班组计件',
                            'workType'      => $workTypeArr[$nid] ?? '手动',
                        ],
                        "where" => " id = '$nid'"
                    ]);
                } else {
                    //新增
                    $warn = static::insert([
                        "table" => self::tableMx,
                        "field" => [
                            'id'            => $nid,
                            'coid'          => self::$coid,
                            'orderId'       => $id,
                            'processId'     => $processIdArr[$k],
                            'mark'          => $markArr[$nid] ?? '否',
                            'price'         => $priceArr[$k],
                            'method'        => $methodArr[$k],
                            'isOut'         => $isOutArr[$nid],
                            'valuationType' => $valuationTypeArr[$k] ?? '班组计件',
                            'workType'      => $workTypeArr[$nid] ?? '手动',
                        ],
                    ]);
                }
                if (!in_array($warn, ['新增成功', '更新成功'])) {
                    $json['warn'] = $warn;
                    break;
                }
            }

            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                $this->commitTrans();
                delete(array('table' => self::tableMx, 'where' => " id not in ('" . implode("','", $mxIdArr) . "') and orderId = '$id'"));
                if ($fileId) {
                    update(array('table' => 'file', 'field' => ['targetId' => $id], 'where' => " targetId = '' and id in ('" . $fileId . "')"));
                }
                if (static::total(array('table' => self::table, "where" => "materialId like '%$field[materialId]%' and materialTypeId = '$field[materialTypeId]' and isDefault = 1 and type = 1")) > 2) {
                    update(array('table' => self::table, 'field' => array('isDefault' => 0), 'where' => "materialId = '$field[materialId]' and type = 1  and id !='$id'"));
                }
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . " id：【" . $id . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = '保存成功';
                $json['warn']     = 2;
                $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=detail&id=" . $id;
            } else {
                $this->rollback();
            }
        }

        resp:
        return json_encode($json, 320);
    }

    /**
     * 启用/停用
     */
    public function stateSwitch(): bool|string
    {
        $type = $this->post('type');
        //生成表单
        $html = $this->layerEdit(array("table" => array(
            array(
                "提示：" => "是否修改所选数据状态为：" . $type,
            ),
        ), 'hidden'                            => hidden(array('name' => 'type', 'value' => $type))));
        //返回
        return $this->layer(array("title" => "状态切换", "height" => 165, "html" => $html, 'formTwo' => 'listForm'));
    }

    /**
     * 启用/停用
     */
    public function stateSwitchEdit(): bool|string
    {
        $idArr = $this->post('id') ? [$this->post('id')] : $this->post('listId');
        $state = $this->post('type');
        if (!$this->power(self::page, "edit")) {
            $json['warn'] = "你没有" . self::title . "的编辑权限";
        } elseif (empty($idArr) || !is_array($idArr)) {
            $json['warn'] = "请选择数据";
        } elseif (!in_array($state, ['启用', '停用'])) {
            $json['warn'] = "类型错误";
        } else {
            $field        = [
                'state' => $state,
            ];
            $json['warn'] = update(array('table' => self::table, 'field' => $field, 'where' => " id in ('" . implode("','", $idArr) . "')"));
            if (in_array($json['warn'], ["新增成功", "更新成功"])) {
                //添加日志
                $type = mb_substr($json['warn'], 0, 2, 'utf-8');
                $text = $this->control['name'] . $type . "了" . self::title . "的状态为【{$state}】， id：【" . implode(",", $idArr) . '】';
                $this->logText(["type" => self::page, "text" => $text]);
                //返回
                $_SESSION['warn'] = $json['warn'];
                $json['warn']     = 2;
            }
        }
        //返回
        return json_encode($json, 320);
    }

    /*详情页*/
    public function detail(): string
    {
        $info = query(self::table, " id = '{$this->get('id')}'");
        if (empty($info['id'])) {
            $html = '未找到此' . self::title;
        } else {
            //菜单
            $data = array(
                "id" => $info['id'],
            );

            $button = [];
            if ($this->power(self::page, "edit")) {
                //按钮
                $button[] = [
                    "name"  => "编辑",
                    "type"  => "顶部页卡",
                    "title" => "编辑用户",
                    "url"   => $this->root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=edit&id=' . $info['id'],
                    'style' => 'li-btn-blue-bg',
                ];
                $state    = $info['state'] == '停用' ? '启用' : '停用';
                $button[] = [
                    "name"  => $state,
                    "type"  => "点击事件",
                    'title' => '修改状态',
                    "fun"   => "layer('" . $this->get('cla') . "','stateSwitch',{id:'" . $info['id'] . "',type:'{$state}'})",
                ];
            }
            if ($this->power(self::page, "del") && $info['state'] == '停用') {
                //按钮
                $button[] = [
                    "name" => "删除",
                    "type" => "弹出层",
                    "cla"  => $this->get('cla'),
                    "fun"  => "operate",
                    "post" => ["act" => 'del', "id" => $info['id']],
                ];
            }
            $result = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list asc"));
            $tr[]   = ['工序名称', '工序委外', '工序节点', '检验方式', '计价方式', '计件单价（' . static::$unit . '）', '报工方式'];
            foreach ($result['array'] as $index => $val) {
                $process = query('process', "id = '$val[processId]'");
                $tr[]    = [$process['name'], $val['isOut'], $val['mark'], $val['method'], $val['valuationType'], self::lostZero($val['price'], 'pricePrecision'), $val['workType']];
            }
            $materialArr  = explode(',', $info['materialId']);
            $materialTr[] = ['物料编码', '物料名称', '规格型号'];
            foreach ($materialArr as $materialId) {
                $material     = query('material', " id = '$materialId'");
                $materialTr[] = [
                    $material['code'],
                    $material['name'],
                    $material['model'],
                ];
            }
            //生成表单
            $data['button'] = $this->tableShowButton($button);
            $data['html'] = $this->tableShow(array(
                "基本信息" => array(
                    array(
                        "工艺路线描述" => $info['description'],
                        "默认工艺"   => $info['isDefault'] ? '是' : '否',
                        '尾工序自动入库' => $info['endProcessIn'],
                        "物料分类" => materialClass::getTypePath($info['materialTypeId']),
                    ),
                    array(
                        "工艺路线编码" => $info['orderNo'],
                        "创建人"    => self::findStaff($info['stid']),
                        "状态"     => $info['state'],
                    ),
                    array(
                        '作业指导书' => fileUploadClass::showSingFile($info['id'], '工艺路线指导书'),
                    ),
                    array(
                        "备注"    => pre($info['text']),
                    ),
                ),
            ));
            $data['html'] .= $this->detailList([
                'title' => '物料',
                'html' => $this->listTable(array('tr' => $materialTr, 'showSort' => true)),
            ]);
            $data['html'] .= $this->detailList([
                'title' => '工序',
                'html' => $this->listTable(array('tr' => $tr, 'showSort' => true)),
            ]);
            //生成页面
            $html = $this->tab($data);
        }
        //返回
        return $html;
    }


    // 操作中转
    public function operate()
    {
        $act  = $this->post('act') ?? '';
        $pwd  = false; // 需要密码
        $form = $power = $word = '';
        switch ($act) {
            default:
                $act      = 'del';
                $msg      = '删除' . self::title;
                $title    = self::page . 'Delete';
                $function = 'delete';
                $form     = self::page . 'OperateForm, listForm';
                $power    = '';
                break;
        }
        if (!$this->power(self::page, $act)) {
            $_SESSION['warn'] = '你还没有' . $msg . '的权限';
            $json             = [
                'warn' => 2,
                'href' => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home',
            ];
        } else {
            return $this->confirm([
                'title'    => $title,
                'function' => $function,
                'form'     => $form,
                'power'    => $power,
                'pwd'      => $pwd,
                'word'     => $word
            ]);
        }

        resp:
        return json_encode($json, 320);
    }


    /**
     * 删除
     * @return bool|string
     */
    public function delete()
    {
        $array = $this->post('listId') ?? $this->post('id');
        if (!$this->power(self::page, "del")) {
            $json['warn'] = "你没有删除的权限";
        } elseif (empty($array)) {
            $json['warn'] = "你一个数据都没有选择呢";
        } else {
            $text  = "";
            $x     = 0;
            $array = is_array($array) ? $array : [$array];
            foreach ($array as $id) {
                $info = query(self::table, " id = '$id' ");
                if ($info['state'] != '停用') {
                    $warn = "不是停用状态，暂不能删除\n";
                } elseif (static::total(array('table' => 'machining_order_mx', 'where' => "coid = '" . self::$coid . "' and routingId = '$id'")) > 0) {
                    $warn = "删除失败：已被使用\n";
                } else {
                    $all = find(array('table' => 'file', 'where' => "targetId = '$id'"));
                    foreach ($all['array'] as $val) {
                        fileDelete($val['src']);
                        delete(array("table" => 'file', "where" => " id = '$val[id]' "));
                    }
                    //最后删除基本参数
                    delete(array("table" => self::table, "where" => " id = '$id' "));
                    delete(array("table" => self::tableMx, "where" => " orderId = '$id' "));
                    //返回
                    $warn = "删除成功";
                    $x++;
                }
                $text .= self::title . "ID【" . $info['id'] . "】,工艺路线【{$info['description']}】" . $warn . "。<br>";
            }
            //添加日志
            $text = $this->control['name'] . "删除了" . self::title . "，结果如下：<br>" . $text;
            $this->logText(array("type" => self::page, "text" => $text));
            $_SESSION['warn'] = "删除了" . $x . "个" . self::title . "，详情见系统日志。";
            $json['warn']     = 2;
            $json['href']     = root . "control/adIndex.html?cla=" . $this->get('cla') . "&fun=home";
        }
        return json_encode($json, 320);
    }
    /**
     * 导入模板字段初始化
     * @return array[]
     */
    public function importFieldInit($classify=''): array
    {
        return match ($classify) {
            default=>  [
                [
                    'columnName'=>'工艺路线描述',
                    'aliasName'=>'工艺路线描述',

                    'isMust'=>true,
                ],
                [
                    'columnName'=>'物料分类',
                    'aliasName'=>'物料分类',

                    'isMust'=>false,
                ],
                [
                    'columnName'=>'物料编码',
                    'aliasName'=>'物料编码(多个用英文,隔开)',

                    'isMust'=>false,
                ],
                [
                    'columnName'=>'物料名称',
                    'aliasName'=>'物料名称',

                    'isMust'=>false,
                ],
                [
                    'columnName'=>'规格型号',
                    'aliasName'=>'规格型号',

                    'isMust'=>false,
                ],
                [
                    'columnName'=>'尾工序自动入库',
                    'aliasName'=>'尾工序自动入库(是/否)',

                    'isMust'=>false,
                ],
                [
                    'columnName'=>'备注',
                    'aliasName'=>'备注',

                    'isMust'=>false,
                ],
                [
                    'columnName'=>'工序编号',
                    'aliasName'=>'工序编号',

                    'isMust'=>true,
                ],
                [
                    'columnName'=>'工序名称',
                    'aliasName'=>'工序名称',

                    'isMust'=>false,
                ],
                [
                    'columnName'=>'工序委外',
                    'aliasName'=>'工序委外(是/否)',

                    'isMust'=>true,
                ],
                [
                    'columnName'=>'工序节点',
                    'aliasName'=>'工序节点(默认否)',

                    'isMust'=>true,
                ],
                [
                    'columnName'=>'检验方式',
                    'aliasName'=>'检验方式(默认免检)',

                    'isMust'=>true,
                ],
                [
                    'columnName'=>'计价方式',
                    'aliasName'=>'计价方式（默认班组计件）',

                    'isMust'=>true,
                ],
                [
                    'columnName'=>'计件单价',
                    'aliasName'=>'计件单价',

                    'isMust'=>false,
                ],
                [
                    'columnName'=>'报工方式',
                    'aliasName'=>'报工方式(默认手动)',

                    'isMust'=>false,
                ],
            ]
        };
    }
}
